package edu.hubu.web.service.impl;

import edu.hubu.web.commons.ObjectUtils;
import edu.hubu.web.commons.ResultsJson;
import edu.hubu.web.commons.StatusCode;
import edu.hubu.web.dao.IBaseDao;
import edu.hubu.web.model.Role;
import edu.hubu.web.model.User;
import edu.hubu.web.model.Verification;
import edu.hubu.web.service.DefaultService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.persistence.EntityManager;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;

public class UserServiceImpl extends DefaultService<User, String> {

    private final BCryptPasswordEncoder encoder;
    private final DefaultService<Role,String> roleService;
    private final DefaultService<Verification,String> verificationService;


    private final EntityManager em;
    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String host;

    public UserServiceImpl(@NotNull IBaseDao<User, String> baseDao, BCryptPasswordEncoder encoder, DefaultService<Role, String> roleService, DefaultService<Verification, String> verificationService, EntityManager em) {
        super(baseDao, User.class,em, "isEntityIsDeleted", "isEntityIsForbidden");
        this.encoder = encoder;
        this.roleService = roleService;
        this.verificationService = verificationService;
        this.em = em;
    }

    public ResultsJson register(User user,String verifyCode){

        user.setUserPassword(encoder.encode(user.getUserPassword()));
        Role role = roleService.getEntityByUniqueField("roleName", "BUYER");
        user.getRoles().add(role);

        //获取验证码
        try {
            IBaseDao<Verification, String> baseDao = verificationService.getBaseDao();
            Optional<Verification> one = baseDao.findOne((ver, criteriaQuery, criteriaBuilder) -> {
                Predicate email = criteriaBuilder.equal(ver.get("verificationEmail"), user.getUserEmail());

                Predicate deactivated = criteriaBuilder.equal(ver.get("verificationIsDeactivated"), false);
                return criteriaQuery.where(email).where(deactivated).getRestriction();
            });
            //验证码不存在
            if(!one.isPresent()){
               return ResultsJson.toJson(StatusCode.SYNTAX_ERROR,1,0,"请先获取验证码！");
            }
            Verification verification= one.get();
            //计算时间差
            Date date = new Date();
            long time = ObjectUtils.Companion.calculateTimeDifference(date, Objects.requireNonNull(verification.getVerificationTimeOutStamp()));

            //判断是否验证成功
            if (time>10){
                verificationService.logicDeleteEntityById(verification.getVerificationId());
                return ResultsJson.toJson(StatusCode.SYNTAX_ERROR,1,0,"验证码超时，请重新获取！");
            }
            if (!verifyCode.equals(verification.getVerificationCode())){
                return ResultsJson.toJson(StatusCode.SYNTAX_ERROR,1,0,"验证码错误！");
            }
            User entity = this.addEntity(user);
            //注册成功，验证码失效
            verificationService.logicDeleteEntityById(verification.getVerificationId());
            return ResultsJson.toJson(StatusCode.SUCCESS,1,0,entity);
        }catch (Exception e){
            e.printStackTrace();
            return ResultsJson.toJson(StatusCode.SYNTAX_ERROR,1,0,"注册失败，请联系管理员");
        }
    }

    public ResultsJson sendEmail(String email){
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setSubject("宋大佬带队-验证码");
            String code = UUID.randomUUID().toString().toUpperCase().substring(0, 6);
            message.setText("您的验证码是： "+code+"。 请在10分钟内输入。");

            //如果验证码存在，失效原有的验证码
            IBaseDao<Verification, String> baseDao = verificationService.getBaseDao();
            Optional<Verification> one = baseDao.findOne((ver, criteriaQuery, criteriaBuilder) -> {

                Predicate emailEntity = criteriaBuilder.equal(ver.get("verificationEmail"), email);

                Predicate deactivated = criteriaBuilder.equal(ver.get("verificationIsDeactivated"), false);
                return criteriaQuery.where(emailEntity).where(deactivated).getRestriction();
            });
            //验证码存在,删除
            if(one.isPresent()){
                verificationService.logicDeleteEntityById(one.get().getVerificationId());
            }
            Verification verification = new Verification();
            Date date = new Date();
            verification.setVerificationCode(code);
            verification.setVerificationEmail(email);
            verification.setVerificationTimeOutStamp(date);
            verificationService.addEntity(verification);
            //发送邮件
            message.setTo(email);
            message.setFrom(host);
            mailSender.send(message);
            return ResultsJson.toJson(StatusCode.SUCCESS,1,0,true);
        }catch (Exception e){
            e.printStackTrace();
            return ResultsJson.toJson(StatusCode.INTERNAL_SERVER_ERROR,1,0,false);
        }
    }


}
